package com.xuelang.pipeline.app.pipeline.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.gson.Gson;
import com.xuelang.hiforce.base.cache.client.service.DistributeCacheManager;
import com.xuelang.hiforce.base.tracing.TracingUtils;
import com.xuelang.hiforce.base.utils.message.Message;
import com.xuelang.jadp.client.sys.dto.NgacAssociateDTO;
import com.xuelang.jadp.client.sys.enums.DeleteFlag;
import com.xuelang.jadp.client.sys.enums.ResourceTypeConstant;
import com.xuelang.pipeline.app.pipeline.DeploymentUnitService;
import com.xuelang.pipeline.app.pipeline.PipelineInstanceService;
import com.xuelang.pipeline.app.pipeline.PipelineSchedulerService;
import com.xuelang.pipeline.app.pipeline.PipelineService;
import com.xuelang.pipeline.app.pipeline.converter.*;
import com.xuelang.pipeline.app.resource.ArtifactToolService;
import com.xuelang.pipeline.app.resource.ConfigMapService;
import com.xuelang.pipeline.app.resource.impl.TektonAnalysisImpl;
import com.xuelang.pipeline.app.resource.request.ArtifactToolQuery;
import com.xuelang.pipeline.app.resource.request.ConfigMapRequest;
import com.xuelang.pipeline.app.resource.util.TektonUtil;
import com.xuelang.pipeline.app.resource.v1beta.pipeline.V1Beta1Pipeline;
import com.xuelang.pipeline.app.resource.v1beta.pipeline.V1Beta1PipelineRun;
import com.xuelang.pipeline.app.task.converter.PipelineConfigTaskDTOToTaskConverter;
import com.xuelang.pipeline.client.application.dto.TraitQuery;
import com.xuelang.pipeline.client.common.constant.Constant;
import com.xuelang.pipeline.client.common.constant.DictConstant;
import com.xuelang.pipeline.client.common.constant.DictDTO;
import com.xuelang.pipeline.client.common.exception.BizException;
import com.xuelang.pipeline.client.common.request.PageParam;
import com.xuelang.pipeline.client.common.result.ApiResult;
import com.xuelang.pipeline.client.common.result.PageRecord;
import com.xuelang.pipeline.client.common.util.BizAssert;
import com.xuelang.pipeline.client.common.util.CryptoUtils;
import com.xuelang.pipeline.client.common.util.RedisHelper;
import com.xuelang.pipeline.client.msg.NotifyReceiverTypeConstant;
import com.xuelang.pipeline.client.pipeline.dto.*;
import com.xuelang.pipeline.client.pipeline.enums.*;
import com.xuelang.pipeline.client.pipeline.utils.DateTimeUtils;
import com.xuelang.pipeline.client.resource.dto.ArtifactToolDTO;
import com.xuelang.pipeline.client.resource.dto.DictQuery;
import com.xuelang.pipeline.client.resource.dto.EnvironmentQuery;
import com.xuelang.pipeline.client.task.dto.PipelineConfigTaskDTO;
import com.xuelang.pipeline.client.task.dto.TaskDefQuery;
import com.xuelang.pipeline.client.task.dto.TaskQuery;
import com.xuelang.pipeline.domain.application.Application;
import com.xuelang.pipeline.domain.application.Component;
import com.xuelang.pipeline.domain.application.Trait;
import com.xuelang.pipeline.domain.application.service.ApplicationDomainService;
import com.xuelang.pipeline.domain.application.service.ComponentDomainService;
import com.xuelang.pipeline.domain.application.service.TraitDomainService;
import com.xuelang.pipeline.domain.pipeline.*;
import com.xuelang.pipeline.domain.pipeline.service.*;
import com.xuelang.pipeline.domain.resource.Cluster;
import com.xuelang.pipeline.domain.resource.Dict;
import com.xuelang.pipeline.domain.resource.Environment;
import com.xuelang.pipeline.domain.resource.Space;
import com.xuelang.pipeline.domain.resource.service.ClusterDomainService;
import com.xuelang.pipeline.domain.resource.service.DictDomainService;
import com.xuelang.pipeline.domain.resource.service.EnvironmentDomainService;
import com.xuelang.pipeline.domain.resource.service.SpaceDomainService;
import com.xuelang.pipeline.domain.task.Task;
import com.xuelang.pipeline.domain.task.TaskDef;
import com.xuelang.pipeline.domain.task.TaskInstance;
import com.xuelang.pipeline.domain.task.service.TaskDefDomainService;
import com.xuelang.pipeline.domain.task.service.TaskDomainService;
import com.xuelang.pipeline.domain.task.service.TaskInstanceDomainService;
import com.xuelang.pipeline.worker.client.crd.IPipelineService;
import com.xuelang.pipeline.worker.client.crd.dto.PipelineRunDTO;
import com.xuelang.pipeline.worker.client.pod.IPodService;
import com.xuelang.pipeline.worker.client.pod.dto.PodQueryDTO;
import com.xuelang.sys.app.sys.NgacManagerService;
import io.kubernetes.client.openapi.models.V1ConfigMap;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.kubernetes.client.util.Yaml;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 流水线服务实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Service
public class PipelineServiceImpl implements PipelineService {

    @Autowired
    PipelineDomainService pipelineDomainService;
    @Autowired
    ComponentDomainService componentDomainService;
    @Autowired
    ApplicationDomainService applicationDomainService;
    @Autowired
    EnvironmentDomainService environmentDomainService;
    @Autowired
    PipelineTemplateDomainService pipelineTemplateDomainService;
    @Autowired
    PipelineTagDomainService pipelineTagDomainService;
    @Autowired
    PipelineGroupDomainService pipelineGroupDomainService;
    @Autowired
    TagDomainService tagDomainService;
    @Autowired
    GroupDomainService groupDomainService;
    @Autowired
    TaskDomainService taskDomainService;
    @Autowired
    DeploymentUnitService deploymentUnitService;
    @Autowired
    TaskDefDomainService taskDefDomainService;
    @Autowired
    TriggerSettingDomainService triggerSettingDomainService;
    @Autowired
    PipelineSchedulerService pipelineSchedulerService;
    @Autowired
    VariableSettingDomainService variableSettingDomainService;
    @Autowired
    CacheSettingDomainService cacheSettingDomainService;
    @Autowired
    private IPipelineService tektonService;
    @Autowired
    private ClusterDomainService clusterDomainService;
    @Autowired
    private SpaceDomainService spaceDomainService;
    @Autowired
    private PipelineInstanceDomainService pipelineInstanceDomainService;
    @Autowired
    private PipelineInstanceService pipelineInstanceService;
    @Autowired
    private TaskInstanceDomainService taskInstanceDomainService;
    @Autowired
    DictDomainService dictDomainService;
    @Autowired
    private TektonAnalysisImpl tektonAnalysis;
    @Autowired
    IPodService podService;
    @Autowired
    private NgacManagerService ngacManagerService;

    @Autowired
    private DistributeCacheManager redisHelper;
    @Autowired
    private ConfigMapService configMapService;
    @Autowired
    private TraitDomainService traitDomainService;
    @Autowired
    private ArtifactToolService artifactToolService;

    private static final Integer BATCH_TRIGGER_MAX_PIPELINES = 5;

    private ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    private Validator validator = factory.getValidator();

    @Override
    public PageRecord<PipelineDTO> pageList(PageParam<PipelineQuery> dtoPageParam) {
        PipelineQuery condition = dtoPageParam.getCondition();
        condition = condition == null ? new PipelineQuery() : condition;
        // 流水线code最终过滤参数
        List<String> finalCodeList = Lists.newArrayList();
        // 根据分组进行过滤
        String group = condition.getGroup();
        if (StringUtils.isNotBlank(group)) {
            List<PipelineGroup> pipelineGroups = pipelineGroupDomainService.queryByGroupUuid(group);
            List<String> codeList = pipelineGroups.stream().map(PipelineGroup::getPipelineCode).collect(Collectors.toList());
            // 如果codeList为空，则直接返回空分页数据
            if (CollectionUtils.isEmpty(codeList)) {
                return new PageRecord<>(
                        dtoPageParam.getCurrentPage(),
                        dtoPageParam.getPageSize(),
                        0L,
                        0L,
                        null);
            }
            finalCodeList.addAll(codeList);
        }

        // 根据流水线code进行过滤
        condition.setCodeList(finalCodeList);

        PageRecord<Pipeline> pageRecord = pipelineDomainService.pageList(
                dtoPageParam.getCurrentPage(),
                dtoPageParam.getPageSize(),
                condition);
        return new PageRecord<>(
                pageRecord.getCurrentPage(),
                pageRecord.getPageSize(),
                pageRecord.getTotalCount(),
                pageRecord.getTotalPages(),
                pageRecord.getRecords().stream().map(PipelineDTOToPipelineConverter.INSTANCE::pipelineToPipelineDTO).collect(Collectors.toList()));
    }

    @Override
    public PageRecord<MyPipelineInfoDTO> pageMyPipelineList(PageParam<MyPipelineQuery> dtoPageParam) {
        MyPipelineQuery condition = dtoPageParam.getCondition();
        PipelineQuery pipelineQuery = MyPipelineQueryToPipelineQueryConverter.INSTANCE.toPipelineQuery(condition);
        PageParam<PipelineQuery> pipelinePageQuery = new PageParam<>();
        pipelinePageQuery.setCurrentPage(1L);
        pipelinePageQuery.setPageSize(Long.MAX_VALUE);
        pipelinePageQuery.setCondition(pipelineQuery);
        PageRecord<PipelineDTO> pipelineDTOPageRecord = pageList(pipelinePageQuery);

        // 若没有数据，则直接返回空
        if (pipelineDTOPageRecord.getTotalCount() == 0) {
            return new PageRecord<>(
                    dtoPageParam.getCurrentPage(),
                    dtoPageParam.getPageSize(),
                    0L,
                    0L,
                    null);
        }

        // 得到信息完善的DTO
        List<MyPipelineInfoDTO> fullfilled = pipelineDTOPageRecord.getRecords().stream().map(this::fullfillMyPipelineInfo).collect(Collectors.toList());
        // 根据条件过滤
        // 根据最后开始时间区间进行过滤
        if (Objects.nonNull(condition.getStartTimeFrom()) || Objects.nonNull(condition.getStartTimeTo())) {
            // 根据MyPipelineInfoDTO的lastRunStartTime进行排序
            Date startTimeFrom = condition.getStartTimeFrom();
            Date startTimeTo = condition.getStartTimeTo();
            fullfilled = fullfilled.stream()
                    .filter(dto -> {
                        Date lastRunStartTime = dto.getLastRunStartTime();
                        return (lastRunStartTime != null &&
                                (startTimeFrom != null && lastRunStartTime.after(startTimeFrom)) &&
                                (startTimeTo != null && lastRunStartTime.before(startTimeTo)));
                    })
                    .collect(Collectors.toList());
        }

        // 根据status进行过滤
        if (Objects.nonNull(condition.getTriggerWay())) {
            Integer triggerWay = condition.getTriggerWay();
            fullfilled = fullfilled.stream()
                    .filter(dto -> triggerWay.equals(dto.getTriggerInfoValue()))
                    .collect(Collectors.toList());
        }

        // 根据status进行过滤
        if (Objects.nonNull(condition.getStatus())) {
            Integer status = condition.getStatus();
            fullfilled = fullfilled.stream()
                    .filter(dto -> status.equals(dto.getStatus()))
                    .collect(Collectors.toList());
        }

        // 根据envUuid进行过滤
        if (StringUtils.isNotBlank(condition.getEnvUuid())) {
            String envUuid = condition.getEnvUuid();
            fullfilled = fullfilled.stream()
                    .filter(dto -> envUuid.equals(dto.getEnvUuid()))
                    .collect(Collectors.toList());
        }

        // 根据appCode进行过滤
        if (StringUtils.isNotBlank(condition.getApplicationCode())) {
            String appCode = condition.getApplicationCode();
            fullfilled = fullfilled.stream()
                    .filter(dto -> appCode.equals(dto.getAppCode()))
                    .collect(Collectors.toList());
        }

        // 根据componentLabel进行过滤
        if (StringUtils.isNotBlank(condition.getComponentLabel())) {
            String componentCode = condition.getComponentLabel();
            fullfilled = fullfilled.stream()
                    .filter(dto -> componentCode.equals(dto.getComponentLabel()))
                    .collect(Collectors.toList());
        }

        // 根据权限进行过滤
        NgacAssociateDTO queryApp = new NgacAssociateDTO();
        queryApp.setObjectType(ResourceTypeConstant.APP);// 资源类型
        queryApp.setTargetUser(TracingUtils.getUserId());// 授权用户
        List<NgacAssociateDTO> appAuthList = ngacManagerService.findNgacAssociate(queryApp);
        NgacAssociateDTO queryComponent = new NgacAssociateDTO();
        queryComponent.setObjectType(ResourceTypeConstant.COMPONENT);// 资源类型
        queryComponent.setTargetUser(TracingUtils.getUserId());// 授权用户
        List<NgacAssociateDTO> componentAuthList = ngacManagerService.findNgacAssociate(queryComponent);
        List<String> componentCodeList = Lists.newArrayList();
        List<String> appCodeList = Lists.newArrayList();
        // 判空
        if (CollectionUtils.isNotEmpty(componentAuthList)) {
            componentCodeList = componentAuthList.stream().map(NgacAssociateDTO::getObjectId).collect(Collectors.toList());
        }
        if (CollectionUtils.isNotEmpty(appAuthList)) {
            appCodeList = appAuthList.stream().map(NgacAssociateDTO::getObjectId).collect(Collectors.toList());
        }
        // 若都为空，则直接返回空结果
        if (CollectionUtils.isEmpty(componentCodeList) && CollectionUtils.isEmpty(appCodeList)) {
            return new PageRecord<>(
                    dtoPageParam.getCurrentPage(),
                    dtoPageParam.getPageSize(),
                    0L,
                    0L,
                    null);
        }
        // 过滤
        List<String> finalAppCodeList = appCodeList;
        List<String> finalComponentCodeList = componentCodeList;
        fullfilled = fullfilled.stream().filter(dto -> finalAppCodeList.contains(dto.getAppCode()) || finalComponentCodeList.contains(dto.getComponentCode()))
                .collect(Collectors.toList());

        // 根据MyPipelineInfoDTO的创建时间进行排序
        fullfilled.sort(Comparator.comparing(MyPipelineInfoDTO::getCreateTime).reversed());

        // 计算分页信息
        long totalCount = fullfilled.size();
        long pageSize = dtoPageParam.getPageSize();
        long totalPages = (totalCount + pageSize - 1) / pageSize;

        // 按照分页参数获取当前页的数据
        int startIndex = (int) ((dtoPageParam.getCurrentPage() - 1) * pageSize);
        int endIndex = (int) Math.min(startIndex + pageSize, totalCount);
        List<MyPipelineInfoDTO> currentPageList = fullfilled.subList(startIndex, endIndex);

        return new PageRecord<>(
                dtoPageParam.getCurrentPage(),
                pageSize,
                totalCount,
                totalPages,
                currentPageList);
    }

    private MyPipelineInfoDTO fullfillMyPipelineInfo(PipelineDTO pipelineDTO) {
        String pipelineCode = pipelineDTO.getCode();
        MyPipelineInfoDTO result = new MyPipelineInfoDTO();
        // 设置创建时间
        result.setCreateTime(pipelineDTO.getCreateTime());
        // 获取标签信息并设置
        List<PipelineTag> pipelineTagList = pipelineTagDomainService.queryByPipelineCode(pipelineCode);
        if (CollectionUtils.isNotEmpty(pipelineTagList)) {
            List<Tag> tagList =
                    tagDomainService.queryByUuidList(pipelineTagList.stream()
                            .map(PipelineTag::getTagUuid)
                            .collect(Collectors.toList()));
            if (CollectionUtils.isNotEmpty(tagList)) {
                List<TagDTO> tagDTOList = tagList.stream().map(TagDTOToTagConverter.INSTANCE::tagToTagDTO).collect(Collectors.toList());
                result.setTagList(tagDTOList);
            }
        }
        // 获取流水线id
        Pipeline pipeline = pipelineDomainService.query(pipelineCode);
        result.setId(pipeline.getId());
        result.setPipelineCode(pipelineCode);
        result.setPipelineName(pipelineDTO.getName());
        // 得到组件code、应用code
        String componentLabel = pipelineDTO.getComponentLabel();
        String appCode = pipelineDTO.getApplicationCode();
        // 设置appCode
        result.setAppCode(appCode);
        // 查询组件
        Component component = componentDomainService.query(componentLabel);
        if (Objects.nonNull(component)) {
            // 设置组件名称
            result.setComponentName(component.getName());
            // 设置组件Label
            result.setComponentLabel(componentLabel);
            // 设置组件
            result.setComponentCode(component.getCode());
        }
        // 查询应用
        Application app = applicationDomainService.query(appCode);
        if (Objects.nonNull(app)) {
            // 设置应用名称
            result.setApplicationName(app.getName());
        }
        // 设置环境名称
        Environment environment = environmentDomainService.query(pipelineDTO.getEnvironmentUuid());
        if (Objects.nonNull(environment)) {
            String envName = environment.getName();
            result.setEnvironmentName(envName);
        }
        // 设置环境uuid
        result.setEnvUuid(pipelineDTO.getEnvironmentUuid());

        // 获取流水线实例
        PipelineInstanceQuery queryInstance = new PipelineInstanceQuery();
        queryInstance.setPipelineCode(pipelineCode);
        List<PipelineInstance> pipelineInstanceList = pipelineInstanceDomainService.listByQuery(queryInstance);
        if (CollectionUtils.isNotEmpty(pipelineInstanceList)) {
            // 设置已执行次数
            result.setExecutedCount(String.valueOf(pipelineInstanceList.size()));
            // 直接取第一个作为当前实例，因为已按照时间进行排序，第一个为最后一个构建的实例
            PipelineInstance pipelineInstance = pipelineInstanceList.get(0);
            // 设置触发信息及实际值
            result.setTriggerInfo(TriggerWayEnum.fromValue(pipelineInstance.getTriggerType()).getDesc());
            result.setTriggerInfoValue(pipelineInstance.getTriggerType());
            // 设置流水线状态
            result.setRecentlyRunStatus(PipelineInstanceEnum.fromKey(pipelineInstance.getPipelineStatus()).getValue());
            // 设置实际状态值
            result.setStatus(pipelineInstance.getPipelineStatus());
            // 设置最后运行开始时间
            result.setLastRunStartTime(pipelineInstance.getStartTime());
            // 设置最后的构建号
            result.setRecentlyBuildNumber(pipelineInstance.getBuildNumber().toString());

            // 查询任务实例
            List<TaskInstance> taskInstanceList = taskInstanceDomainService.queryByPipelineInstanceCode(pipelineInstance.getInstanceCode());
            if (CollectionUtils.isNotEmpty(taskInstanceList)) {
                // 设置任务总数
                result.setTotalTaskCount(String.valueOf(taskInstanceList.size()));
                if (CollectionUtils.isNotEmpty(taskInstanceList)) {
                    // 过滤出最后的任务
                    TaskInstance lastTaskInstance = taskInstanceList.stream()
                            .max(Comparator.comparing(TaskInstance::getStartTime, Comparator.nullsLast(Comparator.naturalOrder())))
                            .orElseThrow(() -> new IllegalStateException("任务实例列表为空"));
                    // 设置最后的任务
                    result.setLastTaskName(lastTaskInstance.getName());
                }
            }
        }

        return result;
    }

    @Override
    public List<PipelineDTO> list(PipelineQuery pipelineQuery) {
        return pipelineDomainService.list(pipelineQuery).stream().map(PipelineDTOToPipelineConverter.INSTANCE::pipelineToPipelineDTO).collect(Collectors.toList());
    }

    @Override
    public Boolean add(PipelineConfigDTO pipelineConfigDTO) {
        PipelineDTO pipelineDTO = pipelineConfigDTO.getBaseInfo();
        BizAssert.notNull(pipelineDTO.getCode(), "流水线编码不能为空");
        BizAssert.notNull(pipelineDTO.getName(), "流水线名称不能为空");
        Pipeline pipeline = PipelineDTOToPipelineConverter.INSTANCE.pipelineDTOToPipeline(pipelineDTO);

        return pipelineDomainService.save(pipeline);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(PipelineConfigDTO pipelineConfigDTO) {
        Boolean ifRunPipeline = pipelineConfigDTO.getIfRunPipeline();
        BizAssert.notNull(ifRunPipeline, "ifRunPipeline不能为空");
        PipelineDTO pipelineDTO = pipelineConfigDTO.getBaseInfo();
        BizAssert.notNull(pipelineDTO.getCode(), "流水线编码不能为空");
        //更新配置态操作
        Pipeline pipeline = updatePipelineConfig(pipelineConfigDTO, pipelineDTO);
        if (ifRunPipeline) {
            // 启动运行流水线
            TriggerPipelineDTO triggerPipelineDTO = TriggerPipelineDTO.builder()
                    .pipelineCode(pipelineDTO.getCode())
                    .triggerType(TriggerWayEnum.MANUAL.getValue())
                    .build();
            Boolean instance = triggerPipelineInstance(triggerPipelineDTO);
            // 运行失败处理
            BizAssert.isTrue(instance, "运行流水线失败");
        }
        return pipelineDomainService.update(pipeline);
    }

    @NotNull
    @Transactional(rollbackFor = Exception.class)
    private Pipeline updatePipelineConfig(PipelineConfigDTO pipelineConfigDTO, PipelineDTO pipelineDTO) {
        //todo 后续拆分..1.基本信息处理，2.流水线编辑  3.环境变量， 4. 缓存  5. 触发方式
        Pipeline pipeline = PipelineDTOToPipelineConverter.INSTANCE.pipelineDTOToPipeline(pipelineDTO);
        pipeline.setUpdaterId(TracingUtils.getUserId());
        String tagUuidList = pipelineDTO.getTagUuidList();
        String tagNameList = pipelineDTO.getTagNameList();
        String groupUuidList = pipelineDTO.getGroupUuidList();
        String groupNameList = pipelineDTO.getGroupNameList();
        List<PipelineConfigTaskDTO> pipelineConfigTaskDTOList = pipelineConfigDTO.getTaskList();
        List<CacheSettingDTO> cacheSettingList = pipelineConfigDTO.getCacheSettingList();
        List<VariableSettingDTO> variableSettingList = pipelineConfigDTO.getVariableSettingList();
        TriggerSettingDTO triggerSetting = pipelineConfigDTO.getTriggerSetting();

        // 检查任务数据是否合规
        if (CollUtil.isNotEmpty(pipelineConfigTaskDTOList)) {
            // 判断是否有重复任务类型
            Set<PipelineConfigTaskDTO> duplicates = pipelineConfigTaskDTOList.stream()
                    .collect(Collectors.groupingBy(
                            PipelineConfigTaskDTO::getTaskDefUuid,
                            Collectors.counting()
                    ))
                    .entrySet().stream()
                    .filter(e -> e.getValue() > 1)
                    .map(e -> pipelineConfigTaskDTOList.stream()
                            .filter(item -> e.getKey().equals(item.getTaskDefUuid()))
                            .findFirst()
                            .get())
                    .collect(Collectors.toSet());
            if (!duplicates.isEmpty()) {
                String duplicatesTaskName = duplicates.stream().map(PipelineConfigTaskDTO::getName).collect(Collectors.joining("，"));
                throw new BizException("同一类型任务定义不允许重复添加【重复的任务定义："+duplicatesTaskName+"】");
            }
            // 重新加入新关联的流水线任务
            pipelineConfigTaskDTOList.forEach(pipelineConfigTaskDTO -> {
                pipelineConfigTaskDTO.setPipelineCode(pipelineDTO.getCode());
                pipelineConfigTaskDTO.setId(null);
                String params = pipelineConfigTaskDTO.getParams();
                try {
                    params = CryptoUtils.decryptByLRSA(Constant.PRIVATE_KEY_L, params);
                    params = (String) JSON.parse(params);
                } catch (Exception e) {
                    log.error("{}.流程编排任务数据解密失败.[异常原因：{}]，[原始数据：{}]",
                            this.getClass().getName(),
                            e.getMessage(),
                            params);
                    //throw new BizException("[流程编排]任务数据疑似被篡改或者配置不正确.");
                }
                pipelineConfigTaskDTO.setParams(params);
            });
        }

        // 先删除掉原流水线编码关联的流水线标签信息
        pipelineTagDomainService.deleteByPipelineCode(pipelineDTO.getCode());
        // 先删除掉原流水线编码关联的流水线分组信息
        pipelineGroupDomainService.deleteByPipelineCode(pipelineDTO.getCode());
        // 先删除掉原流水线任务-流水线编码关联的流水线任务信息
        taskDomainService.deleteByPipelineCode(pipelineDTO.getCode());

        if (CharSequenceUtil.isNotBlank(tagUuidList)) {
            pipeline.setTag(tagNameList);
            // 重新加入新关联的流水线标签
            Arrays.stream(tagUuidList.split(Constant.DEFAULT_DATA_SEPARATOR)).forEach(tagUuid -> {
                PipelineTag pipelineTag = PipelineTag.builder().pipelineCode(pipelineDTO.getCode()).tagUuid(tagUuid).build();
                pipelineTag.setId(null);
                pipelineTag.setCreatorId(TracingUtils.getUserId());
                pipelineTag.setUpdaterId(TracingUtils.getUserId());
                pipelineTagDomainService.save(pipelineTag);
            });
        }
        if (CharSequenceUtil.isNotBlank(groupUuidList)) {
            pipeline.setGroups(groupNameList);
            // 重新加入新关联的流水线分组
            Arrays.stream(groupUuidList.split(Constant.DEFAULT_DATA_SEPARATOR)).forEach(groupUuid -> {
                PipelineGroup pipelineGroup = PipelineGroup.builder().pipelineCode(pipelineDTO.getCode()).groupUuid(groupUuid).build();
                pipelineGroup.setId(null);
                pipelineGroup.setCreatorId(TracingUtils.getUserId());
                pipelineGroup.setUpdaterId(TracingUtils.getUserId());
                pipelineGroupDomainService.save(pipelineGroup);
            });
        }
        if (CollUtil.isNotEmpty(pipelineConfigTaskDTOList)) {
            // 重新加入新关联的流水线任务
            pipelineConfigTaskDTOList.forEach(pipelineConfigTaskDTO -> {
                taskDomainService.save(PipelineConfigTaskDTOToTaskConverter.INSTANCE.pipelineConfigTaskDTOToTask(pipelineConfigTaskDTO));
                saveOrUpdateTrait(pipelineConfigTaskDTO, pipelineDTO);
            });
        }

        // 判断该流水线是否已存在缓存配置
        List<CacheSetting> currentCacheSettingList = cacheSettingDomainService.queryByPipelineCode(pipeline.getCode());
        List<Long> currentCacheSettingIds = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(currentCacheSettingList)) {
            // 获取当前存在的缓存ID列表
            currentCacheSettingIds = currentCacheSettingList.stream()
                    .map(CacheSetting::getId)
                    .collect(Collectors.toList());
        }
        // 判断缓存入参是否为空
        if (CollectionUtils.isNotEmpty(cacheSettingList)) {
            List<CacheSetting> cacheSettingEntityList = cacheSettingList.stream()
                    .map(CacheSettingToDTOConverter.INSTANCE::fromDTO)
                    .peek(setting -> setting.setPipelineCode(pipelineDTO.getCode()))
                    .collect(Collectors.toList());

            // 获取新缓存的ID列表
            List<Long> newIds = cacheSettingEntityList.stream()
                    .map(CacheSetting::getId)
                    .collect(Collectors.toList());

            // 找出在此次未出现的缓存ID列表
            currentCacheSettingIds.removeAll(newIds);
            if (CollUtil.isNotEmpty(currentCacheSettingIds)) {
                // 删除未出现的缓存
                cacheSettingDomainService.removeByIds(currentCacheSettingIds);
            }

            // 拆分为需要新增和需要更新的列表
            List<CacheSetting> settingsToAdd = cacheSettingEntityList.stream()
                    .filter(setting -> setting.getId() == null)
                    .collect(Collectors.toList());

            List<CacheSetting> settingsToUpdate = cacheSettingEntityList.stream()
                    .filter(setting -> setting.getId() != null)
                    .collect(Collectors.toList());

            // 批量新增和更新
            if (CollUtil.isNotEmpty(settingsToAdd)) {
                cacheSettingDomainService.addBatch(settingsToAdd, TracingUtils.getUserId(), new Date());
            }
            if (CollUtil.isNotEmpty(settingsToUpdate)) {
                cacheSettingDomainService.updateBatch(settingsToUpdate, TracingUtils.getUserId(), new Date());
            }
        } else {
            if (CollectionUtils.isNotEmpty(currentCacheSettingIds)) {
                // 若为空则全部删除
                cacheSettingDomainService.removeByIds(currentCacheSettingIds);
            }
        }

        // 判断该流水线是否已存在变量配置
        List<VariableSetting> currentVariableSettingList = variableSettingDomainService.queryByPipelineCode(pipeline.getCode());
        List<Long> currentVariableIdList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(currentVariableSettingList)) {
            // 获取当前存在的变量ID列表
            currentVariableIdList = currentVariableSettingList.stream()
                    .map(VariableSetting::getId)
                    .collect(Collectors.toList());
        }
        if (CollUtil.isNotEmpty(variableSettingList)) {
            List<VariableSetting> settingList = variableSettingList.stream()
                    // 排除掉通用变量，是否通用变量，1是0否
                    .filter(variableSettingDTO -> variableSettingDTO.getIsCommon() != 1)
                    .map(VariableSettingToDTOConverter.INSTANCE::fromDTO)
                    .peek(setting -> setting.setPipelineCode(pipelineDTO.getCode()))
                    .collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(currentVariableIdList)) {

                // 获取新变量的ID列表
                List<Long> newIds = settingList.stream()
                        .map(VariableSetting::getId)
                        .collect(Collectors.toList());

                // 找出在此次未出现的变量ID列表
                currentVariableIdList.removeAll(newIds);
                if (CollUtil.isNotEmpty(currentVariableIdList)) {
                    // 删除未出现的变量
                    variableSettingDomainService.removeByIds(currentVariableIdList);
                }
            }

            // 拆分为需要新增和需要更新的列表
            List<VariableSetting> settingsToAdd = settingList.stream()
                    .filter(setting -> setting.getId() == null)
                    .collect(Collectors.toList());

            List<VariableSetting> settingsToUpdate = settingList.stream()
                    .filter(setting -> setting.getId() != null)
                    .collect(Collectors.toList());

            // 批量新增和更新
            if (CollUtil.isNotEmpty(settingsToAdd)) {
                variableSettingDomainService.addBatch(settingsToAdd, TracingUtils.getUserId(), new Date());
            }
            if (CollUtil.isNotEmpty(settingsToUpdate)) {
                variableSettingDomainService.updateBatch(settingsToUpdate, TracingUtils.getUserId(), new Date());
            }

        } else {
            // 删除当前全部
            if (CollectionUtils.isNotEmpty(currentVariableIdList)) {
                variableSettingDomainService.removeByIds(currentVariableIdList);
            }
        }
        if (Objects.nonNull(triggerSetting)) {
            // 判断单次定时触发是否合规
            String triggerTime = triggerSetting.getTriggerTime();
            Integer triggerWay = triggerSetting.getTriggerWay();
            Integer isClockTrigger = triggerSetting.getIsClockTrigger();
            if (StringUtils.isNotBlank(triggerTime) && Objects.nonNull(isClockTrigger) &&
                    triggerWay.equals(TriggerWayEnum.ONCE.getValue()) &&
                    isClockTrigger.equals(YesOrNoEnum.YES.getValue()) &&
                    !DateTimeUtils.isDateTimeAfterNow(triggerTime, Constant.DEFAULT_DATE_FORMAT, 0)) {
                throw new BizException(Message.code("TRIGGER-TIME-ILLEGAL", triggerTime).getDisplayText());
            }
            TriggerSetting setting = TriggerSettingToDTOConverter.INSTANCE.fromDTO(triggerSetting);
            setting.setPipelineCode(pipelineDTO.getCode());
            // 判断该流水线是否已存在触发配置
            TriggerSetting currentSetting = triggerSettingDomainService.queryByPipelineCode(pipeline.getCode());
            // 标识符，检查触发配置是否发生更新
            boolean isChanged = false;
            // 已存在触发配置，更新
            if (Objects.nonNull(currentSetting)) {
                isChanged = TriggerSetting.clockTriggerDifferences(currentSetting, setting);
                triggerSettingDomainService.update(setting);
            } else {
                // 不存在触发配置，新增
                triggerSettingDomainService.add(setting);
            }

            // 检查定时触发是否开启
            try {
                if (Objects.nonNull(isClockTrigger)) {
                    if (isClockTrigger.equals(YesOrNoEnum.YES.getValue())) {
                        if (isChanged) {
                            pipelineSchedulerService.updateJob(pipeline, setting);
                        } else {
                            // 移除当前定时任务
                            pipelineSchedulerService.removeJob(pipeline);
                            pipelineSchedulerService.addJob(pipeline, setting);
                        }
                    } else {
                        // 移除当前定时任务
                        pipelineSchedulerService.removeJob(pipeline);
                    }
                }
            } catch (SchedulerException e) {
                log.error("定时触发失败", e);
            }
        }
        return pipeline;
    }

    private void saveOrUpdateTrait(PipelineConfigTaskDTO taskConfigDTO, PipelineDTO pipelineDTO) {

        String taskCode = taskConfigDTO.getCode();
        if (taskCode.contains("_deploy")) {
            //存在部署任务，需要写入运维特征，每个组件的环境只运行有一个
            TraitQuery query = new TraitQuery();
            query.setComponentLabel(pipelineDTO.getComponentLabel());
            query.setEnvironmentUuid(pipelineDTO.getEnvironmentUuid());
            List<Trait> traitList = traitDomainService.list(query);
            if (traitList.isEmpty()) {
                Trait trait = new Trait();
                trait.setComponentLabel(pipelineDTO.getComponentLabel());
                trait.setEnvironmentUuid(pipelineDTO.getEnvironmentUuid());
                trait.setApplicationCode(pipelineDTO.getApplicationCode());
                trait.setUuid(IdUtil.fastSimpleUUID());
                setTaskParam(trait, taskConfigDTO);
                trait.setCreateTime(new Date());
                trait.setCreatorId(TracingUtils.getUserId());
                Boolean save = traitDomainService.save(trait);
            } else {
                Trait trait = traitList.get(0);
                setTaskParam(trait, taskConfigDTO);
                trait.setUpdateTime(new Date());
                trait.setUpdaterId(TracingUtils.getUserId());
                Boolean update = traitDomainService.update(trait);
            }
        }
    }

    private void setTaskParam(Trait trait, PipelineConfigTaskDTO taskConfigDTO) {
        Gson gson = new Gson();
        HashMap<String, String> taskParamMap = gson.fromJson(taskConfigDTO.getParams(), HashMap.class);
        trait.setCpu(String.valueOf(taskParamMap.get(DeployTaskFieldEnum.cpu.getKey())));
        trait.setReplicas(new BigDecimal(String.valueOf(taskParamMap.get(DeployTaskFieldEnum.replicas.getKey()))).intValueExact());
        trait.setPort(new BigDecimal(String.valueOf(taskParamMap.get(DeployTaskFieldEnum.port.getKey()))).intValueExact());
        trait.setInternalStorage(String.valueOf(taskParamMap.get(DeployTaskFieldEnum.memory.getKey())));
        trait.setDomainName(taskParamMap.get(DeployTaskFieldEnum.domain.getKey()));
        trait.setConfiguration(taskParamMap.get(DeployTaskFieldEnum.advancedConfig.getKey()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(String code) {
        BizAssert.notNull(code, "流水线编码不能为空");
        // 删除流水线任务
        taskDomainService.deleteByPipelineCode(code);
        // 删除流水线任务实例
        List<PipelineInstanceDTO> pipelineInstanceDTOS = pipelineInstanceService.listByPipelineCode(code);
        if (CollectionUtils.isNotEmpty(pipelineInstanceDTOS)) {
            List<String> pipelineInstanceCodeList = pipelineInstanceDTOS.stream()
                    .map(PipelineInstanceDTO::getInstanceCode)
                    .collect(Collectors.toList());
            taskInstanceDomainService.removeByPipelineInstanceCodeList(pipelineInstanceCodeList);
            // 删除部署单
            deploymentUnitService.removeByCodes(pipelineInstanceCodeList);
        }
        // 删除流水线实例
        pipelineInstanceService.removeByCodes(Collections.singletonList(code));
        // 删除流水线缓存配置
        cacheSettingDomainService.removeByCodes(Collections.singletonList(code));
        // 删除流水线触发配置
        triggerSettingDomainService.removeByCodes(Collections.singletonList(code));
        // 删除流水线分组
        pipelineGroupDomainService.deleteByPipelineCode(code);
        // 删除流水线tag
        pipelineTagDomainService.deleteByPipelineCode(code);

        return pipelineDomainService.delete(code);
    }

    @Override
    public PipelineDTO query(String code) {
        BizAssert.notNull(code, "流水线编码不能为空");
        Pipeline query = pipelineDomainService.query(code);
        PipelineDTO pipelineDTO = PipelineDTOToPipelineConverter.INSTANCE.pipelineToPipelineDTO(query);
        if (pipelineDTO != null) {
            List<PipelineGroup> pipelineGroupList = pipelineGroupDomainService.list(PipelineGroup.builder().pipelineCode(code).build());
            List<PipelineTag> pipelineTagList = pipelineTagDomainService.list(PipelineTag.builder().pipelineCode(code).build());
            // setGroupUuidList
            Optional.ofNullable(pipelineGroupList).ifPresent(
                    groupList -> pipelineDTO.setGroupUuidList(groupList.stream().map(PipelineGroup::getGroupUuid).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
            );
            // setTagUuidList
            Optional.ofNullable(pipelineTagList).ifPresent(
                    tagList -> pipelineDTO.setTagUuidList(tagList.stream().map(PipelineTag::getTagUuid).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
            );
            // setGroupNameList
            Optional.ofNullable(pipelineDTO.getGroupUuidList()).flatMap(
                            groupUuidList -> Optional.ofNullable(groupDomainService.listByUuidList(Arrays.asList(groupUuidList.split(Constant.DEFAULT_DATA_SEPARATOR)))))
                    .ifPresent(
                            groupList -> pipelineDTO.setGroupNameList(groupList.stream().map(Group::getName).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
                    );
            // setTagNameList
            Optional.ofNullable(pipelineDTO.getTagUuidList()).flatMap(
                            tagUuidList -> Optional.ofNullable(tagDomainService.listByUuidList(Arrays.asList(tagUuidList.split(Constant.DEFAULT_DATA_SEPARATOR)))))
                    .ifPresent(
                            tagList -> pipelineDTO.setTagNameList(tagList.stream().map(Tag::getName).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
                    );
            // setApplicationName
            pipelineDTO.setApplicationName(applicationDomainService.query(pipelineDTO.getApplicationCode()).getName());
            // setEnvironmentName
            pipelineDTO.setEnvironmentName(environmentDomainService.query(pipelineDTO.getEnvironmentUuid()).getName());
            // setProjectName
            pipelineDTO.setProjectName(Constant.DEFAULT_PROJECT_NAME);

            // 查询组件
            Component component = componentDomainService.query(query.getComponentLabel());
            if (Objects.nonNull(component)) {
                // 设置组件code
                pipelineDTO.setComponentCode(component.getCode());
            }

            // 找到当前用户的收藏夹分组
            GroupQuery groupQuery = new GroupQuery();
            groupQuery.setName(Constant.DEFAULT_MY_FAVORITE);
            groupQuery.setIsDefault(1);
            List<Group> targetGroupResult = groupDomainService.list(groupQuery);
            Group myFavorite = targetGroupResult.get(0);

            List<PipelineGroup> favoriteGroupList = pipelineGroupDomainService.queryByGroupUuid(myFavorite.getUuid());
            List<String> filterResult = favoriteGroupList.stream()
                    .map(PipelineGroup::getPipelineCode)
                    .filter(p -> p.contains(code))
                    .collect(Collectors.toList());
            pipelineDTO.setIsFavorite(CollectionUtils.isNotEmpty(filterResult));
        }

        return pipelineDTO;
    }

    @Override
    public List<PipelineDTO> queryByComponentLabel(String componentLabel) {
        return pipelineDomainService.queryByComponentLabel(componentLabel).stream()
                .map(PipelineDTOToPipelineConverter.INSTANCE::pipelineToPipelineDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComponentPipelineDTO componentPipeline(ComponentPipelineQuery pipelineQuery) {
        BizAssert.notEmpty(pipelineQuery.getComponentLabel(), "组件标签不能为空");
        BizAssert.notEmpty(pipelineQuery.getEnvironmentUuid(), "环境唯一标识不能为空");

        List<Pipeline> pipelineList = pipelineDomainService.list(
                Pipeline.builder()
                        .componentLabel(pipelineQuery.getComponentLabel())
                        .environmentUuid(pipelineQuery.getEnvironmentUuid())
                        .build());
        Pipeline pipeline = CollUtil.getFirst(pipelineList);

        EnvironmentQuery environmentQuery = new EnvironmentQuery();
        environmentQuery.setApplicationCode(pipelineQuery.getApplicationCode());
        List<Environment> environmentList = environmentDomainService.list(environmentQuery);
        // 需判断流水线是否为空且 环境是否为空
        if (pipeline == null && CollectionUtils.isNotEmpty(environmentList)) {
            Component component = componentDomainService.query(pipelineQuery.getComponentLabel());
            BizAssert.notNull(component, "组件信息不存在");

            final String newPipelineCode = IdUtil.fastSimpleUUID();

            pipeline = new Pipeline();
            pipeline.setCode(newPipelineCode);
            pipeline.setProjectCode(Constant.DEFAULT_PROJECT_CODE);
            pipeline.setEnvironmentUuid(pipelineQuery.getEnvironmentUuid());
            pipeline.setComponentLabel(pipelineQuery.getComponentLabel());
            pipeline.setApplicationCode(component.getApplicationCode());

            List<PipelineTemplate> pipelineTemplateList = pipelineTemplateDomainService.list(PipelineTemplate.builder().componentType(component.getComponentType()).programLanguage(component.getProgramLanguage()).build());
            boolean existsPipelineTemplate = CollUtil.isNotEmpty(pipelineTemplateList);
            if (existsPipelineTemplate) {
                // 拷贝模板流水线信息到流水线
                PipelineTemplate pipelineTemplate = pipelineTemplateList.get(0);
                pipeline.setName(pipelineTemplate.getName());
                // 批量拷贝流水线模板的流水线任务到流水线
                taskDomainService.batchSaveByPipelineTemplateUuid(pipelineTemplate.getUuid(), newPipelineCode, TracingUtils.getUserId());
                // 拷贝流水线模板的流水线变量设置到流水线
                variableSettingDomainService.batchSaveByPipelineTemplateUuid(pipelineTemplate.getUuid(), newPipelineCode, TracingUtils.getUserId());
            } else {
                // 创建流水线
                pipeline.setName(Constant.DEFAULT_NEW_PIPELINE_NAME_PREFIX + DateUtil.now());
            }
            // 拷贝通用变量设置到该流水线的变量设置中
            List<Dict> pipelineCommonVariableList = dictDomainService.list(DictQuery.builder().dictType(DictConstant.DICT_TYPE_PIPELINE_COMMON_VARIABLE).build());
            if (CollUtil.isNotEmpty(pipelineCommonVariableList)) {
                List<VariableSetting> variableSettingList = new ArrayList<>();
                final Pipeline refPipeline = pipeline;
                pipelineCommonVariableList.forEach(dict ->
                        variableSettingList.add(
                                VariableSetting.builder()
                                        .pipelineCode(newPipelineCode)
                                        .name(dict.getDictValue())
                                        .defaultValue(existsPipelineTemplate ? getComponentVariableValueByDictCode(dict, refPipeline) : dict.getDictValue())
                                        .isRunSetting(0)
                                        .isRunSelect(0)
                                        .isPrivate(1)
                                        .isCommon(1)
                                        .build())
                );
                variableSettingDomainService.addBatch(variableSettingList, TracingUtils.getUserId(), new Date());
            }

            pipelineDomainService.save(pipeline);
        }
        // 流水线运行状态数据
        ComponentPipelineDTO componentPipelineDTO = fullfillComponentPipelineInfo(pipeline);
        return componentPipelineDTO;
    }

    private ComponentPipelineDTO fullfillComponentPipelineInfo(Pipeline pipeline) {
        String pipelineCode = pipeline.getCode();
        ComponentPipelineDTO result = new ComponentPipelineDTO();
        result.setPipelineCode(pipelineCode);
        result.setPipelineName(pipeline.getName());

        // 获取流水线实例
        PipelineInstanceQuery queryInstance = new PipelineInstanceQuery();
        queryInstance.setPipelineCode(pipelineCode);
        List<PipelineInstance> pipelineInstanceList = pipelineInstanceDomainService.listByQuery(queryInstance);
        if (CollectionUtils.isNotEmpty(pipelineInstanceList)) {
            // 设置已执行次数
            result.setExecutedCount(String.valueOf(pipelineInstanceList.size()));
            // 直接取第一个作为当前实例，因为已按照时间进行排序，第一个为最后一个构建的实例
            PipelineInstance pipelineInstance = pipelineInstanceList.get(0);
            // 设置触发信息及实际值
            result.setTriggerInfo(TriggerWayEnum.fromValue(pipelineInstance.getTriggerType()).getDesc());
            // 设置流水线状态
            result.setRecentlyRunStatus(PipelineInstanceEnum.fromKey(pipelineInstance.getPipelineStatus()).getValue());
            // 设置实际状态值
            result.setRecentlyRunStatus(PipelineInstanceEnum.fromKey(pipelineInstance.getPipelineStatus()).getValue());
            // 设置最后运行开始时间
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            result.setRecentlyRunStartTime(sdf.format(pipelineInstance.getStartTime()));
            // 设置最后的构建号
            result.setRecentlyBuildNumber(pipelineInstance.getBuildNumber().toString());

            // 查询任务实例
            List<TaskInstance> taskInstanceList = taskInstanceDomainService.queryByPipelineInstanceCode(pipelineInstance.getInstanceCode());
            if (CollectionUtils.isNotEmpty(taskInstanceList)) {
                // 设置任务总数
                result.setTotalTaskCount(String.valueOf(taskInstanceList.size()));
                if (CollectionUtils.isNotEmpty(taskInstanceList)) {
                    // 过滤出最后的任务
                    TaskInstance lastTaskInstance = taskInstanceList.stream()
                            .max(Comparator.comparing(TaskInstance::getStartTime, Comparator.nullsLast(Comparator.naturalOrder())))
                            .orElseThrow(() -> new IllegalStateException("任务实例列表为空"));
                    // 设置最后的任务
                    result.setRecentlyRunStage(lastTaskInstance.getName());
                }
            }
        }

        return result;
    }

    /**
     * 通过dictCode获取组件变量值
     *
     * @param dict
     * @param pipeline
     * @return
     */
    private String getComponentVariableValueByDictCode(Dict dict, Pipeline pipeline) {
        // TODO: 这里代码需要优化掉if else
        if (DictConstant.DICT_CODE_COMPONENT_DEPLOY_ENV.equals(dict.getDictCode())) {
            Environment environment = environmentDomainService.query(pipeline.getEnvironmentUuid());
            return Optional.ofNullable(environment).map(Environment::getCode).orElse(dict.getDictValue());
        } else if (DictConstant.DICT_CODE_COMPONENT_DEPLOY_TOKEN.equals(dict.getDictCode())) {
            Component component = componentDomainService.query(pipeline.getComponentLabel());
            return Optional.ofNullable(component).map(Component::getGitToken).orElse(dict.getDictValue());
        } else if (DictConstant.DICT_CODE_COMPONENT_CODE_REPOSITORY.equals(dict.getDictCode())) {
            Component component = componentDomainService.query(pipeline.getComponentLabel());
            return Optional.ofNullable(component).map(Component::getCodeRepository).orElse(dict.getDictValue());
        } else if (DictConstant.DICT_CODE_COMPONENT_CODE_BRANCH.equals(dict.getDictCode())) {
            return Constant.PIPELINE_TEMPLATE_VARIABLE_BRANCH_VALUE;
        }
        return dict.getDictValue();
    }

    @Override
    public PipelineConfigDTO pipelineConfig(String code) {
        BizAssert.notEmpty(code, "流水线编码不能为空.");
        Pipeline pipeline = pipelineDomainService.query(code);
        BizAssert.notNull(pipeline, "未查询到对应流水线信息.");
        PipelineDTO pipelineDTO = PipelineDTOToPipelineConverter.INSTANCE.pipelineToPipelineDTO(pipeline);
        // 查询组件
        Component component = componentDomainService.query(pipelineDTO.getComponentLabel());
        if (Objects.nonNull(component)) {
            // 设置组件编码
            pipelineDTO.setComponentCode(component.getCode());
        }
        // setProjectName
        pipelineDTO.setProjectName(Constant.DEFAULT_PROJECT_NAME);
        // setApplicationName
        pipelineDTO.setApplicationName(applicationDomainService.query(pipeline.getApplicationCode()).getName());
        // setEnvironmentName
        pipelineDTO.setEnvironmentName(environmentDomainService.query(pipeline.getEnvironmentUuid()).getName());
        List<PipelineGroup> pipelineGroupList = pipelineGroupDomainService.list(PipelineGroup.builder().pipelineCode(code).build());
        List<PipelineTag> pipelineTagList = pipelineTagDomainService.list(PipelineTag.builder().pipelineCode(code).build());
        // setGroupUuidList
        Optional.ofNullable(pipelineGroupList).ifPresent(
                groupList -> pipelineDTO.setGroupUuidList(groupList.stream().map(PipelineGroup::getGroupUuid).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
        );
        // setTagUuidList
        Optional.ofNullable(pipelineTagList).ifPresent(
                tagList -> pipelineDTO.setTagUuidList(tagList.stream().map(PipelineTag::getTagUuid).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
        );
        // setGroupNameList
        Optional.ofNullable(pipelineDTO.getGroupUuidList()).flatMap(
                        groupUuidList -> Optional.ofNullable(groupDomainService.listByUuidList(Arrays.asList(groupUuidList.split(Constant.DEFAULT_DATA_SEPARATOR)))))
                .ifPresent(
                        groupList -> pipelineDTO.setGroupNameList(groupList.stream().map(Group::getName).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
                );
        // setTagNameList
        Optional.ofNullable(pipelineDTO.getTagUuidList()).flatMap(
                        tagUuidList -> Optional.ofNullable(tagDomainService.listByUuidList(Arrays.asList(tagUuidList.split(Constant.DEFAULT_DATA_SEPARATOR)))))
                .ifPresent(
                        tagList -> pipelineDTO.setTagNameList(tagList.stream().map(Tag::getName).collect(Collectors.joining(Constant.DEFAULT_DATA_SEPARATOR)))
                );
        // setTaskList
        List<Task> taskList = taskDomainService.list(TaskQuery.builder().pipelineCode(code).build());
        List<PipelineConfigTaskDTO> pipelineConfigTaskDTOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(taskList)) {
            pipelineConfigTaskDTOList = taskList.stream().map(PipelineConfigTaskDTOToTaskConverter.INSTANCE::taskToPipelineConfigTaskDTO).collect(Collectors.toList());
            pipelineConfigTaskDTOList.forEach(taskDTO -> {
                // 增加流水线任务定义schema信息
                Optional.ofNullable(taskDefDomainService.query(taskDTO.getTaskDefUuid()))
                        .ifPresent(taskDef -> taskDTO.setSchema(taskDef.getSchemaConfig()));
            });
        }
        // 查询流水线缓存设置
        List<CacheSettingDTO> cacheSettingList = Optional.ofNullable(cacheSettingDomainService.queryByPipelineCode(code)).orElse(new ArrayList<>()).stream()
                .map(CacheSettingToDTOConverter.INSTANCE::toDTO).collect(Collectors.toList());
        // 查询流水线变量设置
        List<VariableSettingDTO> variableSettingList = Optional.ofNullable(variableSettingDomainService.queryByPipelineCode(code)).orElse(new ArrayList<>()).stream()
                .map(VariableSettingToDTOConverter.INSTANCE::toDTO).collect(Collectors.toList());
        // 拷贝通用变量设置到该流水线的变量设置中，放在列表头部
        /*
        List<Dict> pipelineCommonVariableList = dictDomainService.list(DictQuery.builder().dictType(DictConstant.DICT_TYPE_PIPELINE_COMMON_VARIABLE).build());
        if (CollUtil.isNotEmpty(pipelineCommonVariableList)) {
            final Pipeline refPipeline = pipeline;
            pipelineCommonVariableList.forEach(dict ->
                    variableSettingList.add(0,
                            VariableSettingDTO.builder()
                                    .pipelineCode(code)
                                    .name(dict.getDictCode())
                                    .defaultValue(getComponentVariableValueByDictCode(dict, refPipeline))
                                    .isRunSetting(0)
                                    .isRunSelect(0)
                                    .isPrivate(1)
                                    .isCommon(1)
                                    .build())
            );
        }
        */
        // 查询流水线触发器设置
        TriggerSettingDTO triggerSetting = TriggerSettingToDTOConverter.INSTANCE.toDTO(triggerSettingDomainService.queryByPipelineCode(code));
        return PipelineConfigDTO.builder()
                .baseInfo(pipelineDTO)
                .taskList(pipelineConfigTaskDTOList)
                .cacheSettingList(cacheSettingList)
                .variableSettingList(variableSettingList)
                .triggerSetting(triggerSetting)
                .build();
    }


    @Override
    public List<DictDTO> queryDeployEnvDict(DeployCompTaskQuery deployCompTaskQuery) {
        List<DictDTO> dtoList = new ArrayList<>();
        //根据code  获取流水线是部署哪个环境
        Pipeline pipeline = pipelineDomainService.query(deployCompTaskQuery.getPipelineId());
        if (Objects.isNull(pipeline)) {
            //用于模版。特殊处理。获取不到内容。不报错。返回变量
            DictDTO dictDTO = new DictDTO();
            dictDTO.setText("{{componentDeployEnv}}");
            dictDTO.setId("{{componentDeployEnv}}");
            dtoList.add(dictDTO);
            return dtoList;
//            throw new BizException(Message.code("PIPELINE-NOT-EXIST", deployCompTaskQuery.getPipelineId()).getDisplayText());
        }
        String environmentUuid = pipeline.getEnvironmentUuid();
        Environment environment = environmentDomainService.query(environmentUuid);
        DictDTO dictDTO = new DictDTO();
        dictDTO.setId(environment.getCode());
        dictDTO.setText(environment.getName());
        dtoList.add(dictDTO);
        return dtoList;
    }

    @Override
    public String queryYamlConfig(String pipelineCode) {

        PipelineConfigDTO pipelineConfig = pipelineConfig(pipelineCode);
        List<TaskDef> taskDefs = taskDefDomainService.pageList(1, 100, TaskDefQuery.builder().build()).getRecords();
        V1Beta1Pipeline v1Beta1Pipeline = tektonAnalysis.getV1Beta1Pipeline(pipelineConfig, taskDefs);
        return Yaml.dump(v1Beta1Pipeline);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean triggerPipelineInstance(TriggerPipelineDTO triggerPipelineDTO) {
        // 停止现有运行中的流水线
        cancelPipelineInstance(triggerPipelineDTO.getPipelineCode());

        Assert.notNull(triggerPipelineDTO.getTriggerType(), "触发方式不能为空");
        //获取配置态
        PipelineConfigDTO pipelineConfig = pipelineConfig(triggerPipelineDTO.getPipelineCode());
        //获取集群信息
        Environment environment = environmentDomainService.query(pipelineConfig.getBaseInfo().getEnvironmentUuid());
        Cluster cluster = getClusterByEnv(environment);

        PipelineInstance pipelineInstance = getPipelineInstanceByConfig(pipelineConfig, triggerPipelineDTO.getTriggerType());
        pipelineInstance.setRemark(triggerPipelineDTO.getRemark());
        //   1. 根据配置态流水线、任务信息创建流水线实例、任务实例信息
        pipelineInstanceDomainService.add(pipelineInstance);
        List<TaskDef> taskDefs = taskDefDomainService.pageList(1, 100, TaskDefQuery.builder().build()).getRecords();
        addTaskInstanceByConfig(pipelineConfig, pipelineInstance.getInstanceCode(), taskDefs);
        //   2. 流水线实例，任务实例，配置变量，缓存解析成 tekton pipeline, pipelineRun的结构
        //   3. 调用worker服务，创建或更新对应的pipeline
        V1Beta1Pipeline v1Beta1Pipeline = tektonAnalysis.getV1Beta1Pipeline(pipelineConfig, taskDefs);

        com.xuelang.pipeline.worker.client.crd.dto.PipelineDTO pipelineDTO = new com.xuelang.pipeline.worker.client.crd.dto.PipelineDTO();
        pipelineDTO.setV1Beta1PipelineStr(JSON.toJSONString(v1Beta1Pipeline));
        pipelineDTO.setNamespaceName(v1Beta1Pipeline.getMetadata().getNamespace());
        pipelineDTO.setKubeConfig(cluster.getKubeConfig());
        try {
            com.xuelang.pipeline.worker.client.common.result.ApiResult<Boolean> v1pipelineResult = tektonService.createPipeline(pipelineDTO);
        } catch (Exception e) {
            log.info("调用worker服务创建pipeline失败", e);
            throw new BizException("流水线配置有误，解析流水线失败！");
        }
        String v1Beta1PipelineRunStr;
        V1Beta1PipelineRun v1Beta1PipelineRun;
        try {
            // 解析创建pipelineRun
            v1Beta1PipelineRun = tektonAnalysis.getV1Beta1PipelineRun(pipelineConfig, pipelineInstance, taskDefs);
            v1Beta1PipelineRunStr = JSON.toJSONString(v1Beta1PipelineRun);
        } catch (Exception e) {
            log.error("获取配置流水线参数，解析失败", e);
            throw new BizException("流水线配置有误，解析流水线失败！");
        }

        //人工卡点处理状态处理
        if (v1Beta1PipelineRunStr.contains("approve-")) {
            ConfigMapRequest request = new ConfigMapRequest();
            request.setKubeConfig(cluster.getKubeConfig());
            request.setNamespaceName(v1Beta1PipelineRun.getMetadata().getNamespace());
            String uniqueCode = pipelineConfig.getBaseInfo().getComponentLabel() + "-" + environment.getCode();
            request.setV1ConfigMap(getV1ConfigMap(uniqueCode));
            request.setConfigMapName("approve-" + uniqueCode);
            request.setData(getApproveInitMap());
            try {
                ApiResult<Boolean> result = configMapService.saveOrUpdate(request);
            } catch (Exception e) {
                log.info("调用worker服务创建configmap失败", e);
                throw new BizException("流水线运行失败！设置人工卡点有误");
            }
        }
        PipelineRunDTO pipelineRunDTO = new PipelineRunDTO();
        pipelineRunDTO.setV1Beta1PipelineRunStr(v1Beta1PipelineRunStr);
        pipelineRunDTO.setKubeConfig(cluster.getKubeConfig());
        pipelineRunDTO.setNamespaceName(v1Beta1PipelineRun.getMetadata().getNamespace());
        try {
            com.xuelang.pipeline.worker.client.common.result.ApiResult<Boolean> v1pipelineRunResult = tektonService.createPipelineRun(pipelineRunDTO);
        } catch (Exception e) {
            log.info("调用worker服务创建pipelineRun失败", e);
            throw new BizException("流水线配置有误，运行流水线失败！");
        }
        //   4. 添加至轮询.... send redis
        redisHelper.enqueue(Constant.WAIT_RUNNING_PIPELINE_QUEUE_KEY, pipelineInstance.getInstanceCode());
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchTriggerPipelineInstance(List<String> pipelineCodeList) {
        // 非空校验
        if (CollectionUtils.isEmpty(pipelineCodeList)) {
            return true;
        }
        // 校验批量个数是否超过最大值
        if (pipelineCodeList.size() > BATCH_TRIGGER_MAX_PIPELINES) {
            throw new BizException("单次批量触发流水线的条数不可超过" + BATCH_TRIGGER_MAX_PIPELINES + "条!");
        }

        // 将dtoList转化为队列
        Queue<TriggerPipelineDTO> dtoQueue = pipelineCodeList.stream().map(p -> {
            TriggerPipelineDTO dto = new TriggerPipelineDTO();
            dto.setPipelineCode(p);
            dto.setTriggerType(3);
            return dto;
        }).collect(Collectors.toCollection(LinkedList::new));

        // 根据队列FIFO触发流水线
        while (!dtoQueue.isEmpty()) {
            TriggerPipelineDTO dto = dtoQueue.poll();  // 获取并移除队列头部元素
            try {
                triggerPipelineInstance(dto);  // 调用触发方法
            } catch (Exception e) {
                // 捕获异常并记录日志
                log.error("Failed to trigger pipeline instance for pipeline code: {}", dto.getPipelineCode(), e);
                throw e;  // 或者根据需要进行进一步处理
            }
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelPipelineInstance(String pipelineCode) {
        //获取配置态
        PipelineConfigDTO pipelineConfig = pipelineConfig(pipelineCode);
        //获取集群信息
        Environment environment = environmentDomainService.query(pipelineConfig.getBaseInfo().getEnvironmentUuid());
        Cluster cluster = getClusterByEnv(environment);

        PipelineInstanceQuery query = new PipelineInstanceQuery();
        query.setPipelineCode(pipelineCode);
        List<PipelineInstance> listResult = pipelineInstanceDomainService.listByQuery(query);
        if (CollectionUtils.isEmpty(listResult) ||
                !listResult.get(0).getPipelineStatus().equals(PipelineInstanceEnum.running.getKey())) {
            //没有执行实例的情况
            return true;
        }
        PipelineInstance pipelineInstance = listResult.get(0);
        pipelineInstance.setPipelineStatus(PipelineInstanceEnum.terminated.getKey());
        pipelineInstance.setEndTime(new Date());
        // 更新流水线实例信息
        pipelineInstanceDomainService.update(pipelineInstance);

        // 更新任务状态
        List<TaskInstance> taskInstanceList = taskInstanceDomainService.queryByPipelineInstanceCode(pipelineInstance.getInstanceCode());
        if (CollectionUtils.isNotEmpty(taskInstanceList)) {
            taskInstanceList.forEach(t -> {
                if (t.getTaskStatus().equals(TaskInstanceEnum.running.getKey())) {
                    t.setTaskStatus(TaskInstanceEnum.terminated.getKey());
                    t.setEndTime(new Date());
                    taskInstanceDomainService.update(t);
                }
            });
        }

        PipelineRunDTO pipelineRunDTO = new PipelineRunDTO();
        pipelineRunDTO.setPipelineRunName(pipelineInstance.getInstanceCode());
        pipelineRunDTO.setNamespaceName(Constant.BUILD_NAMESPACE);
        pipelineRunDTO.setKubeConfig(cluster.getKubeConfig());
        com.xuelang.pipeline.worker.client.common.result.ApiResult<Boolean> cancelPipelineRun = tektonService.cancelPipelineRun(pipelineRunDTO);

        return cancelPipelineRun.getData();
    }

    private V1ConfigMap getV1ConfigMap(String uniqueCode) {
        V1ConfigMap configMap = new V1ConfigMap();
        configMap.setApiVersion("v1");
        configMap.setKind("ConfigMap");
        V1ObjectMeta meta = new V1ObjectMeta();
        meta.setNamespace(Constant.BUILD_NAMESPACE);
        meta.setName("approve-" + uniqueCode);
        configMap.setMetadata(meta);
        Map<String, String> data = getApproveInitMap();
        configMap.setData(data);
        return configMap;
    }


    private Map<String, String> getApproveInitMap() {
        Map<String, String> data = new HashMap<>();
        data.put("status", "wait");
        return data;
    }

    @Override
    public void downloadTaskLog(String envId, String podName, String containerName, HttpServletResponse response) {
        Environment environment = environmentDomainService.query(envId);
        BizAssert.notNull(environment, "环境不存在");
        Space space = spaceDomainService.query(environment.getSpaceUuid());
        BizAssert.notNull(space, "交付空间不存在");
        Cluster cluster = clusterDomainService.query(space.getClusterUuid());
        BizAssert.notNull(cluster, "集群不存在");

//        PodLogRequest podLogRequest = new PodLogRequest();
//        podLogRequest.setKubeConfig(cluster.getKubeConfig());
//        // 使用默认的namespace
//        podLogRequest.setNamespaceName(Constant.BUILD_NAMESPACE);
//        podLogRequest.setContainer(containerName);
//        podLogRequest.setPodName(podName);
//        podLogRequest.setTailLines(500);

        PodQueryDTO podLogRequest = new PodQueryDTO();
        podLogRequest.setKubeConfig(cluster.getKubeConfig());
        // 使用默认的namespace
        podLogRequest.setNamespaceName(Constant.BUILD_NAMESPACE);
        podLogRequest.setContainer(containerName);
        podLogRequest.setPodName(podName);
        podLogRequest.setTailLines(500);

        com.xuelang.pipeline.worker.client.common.result.ApiResult<String> logResult = podService.getPodLog(podLogRequest);
        String logContent = logResult.getData();

        // 将日志字符串写入 HttpServletResponse
        try (InputStream inputStream = new ByteArrayInputStream(logContent.getBytes());
             OutputStream outputStream = response.getOutputStream()) {

            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + podName + ".log");

            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            throw new IllegalStateException("Error writing log to response", e);
        }

    }

    @Override
    public List<String> findPipelineNotifyReceiverList(String pipelineCode) {
        TriggerSetting triggerSetting = triggerSettingDomainService.queryByPipelineCode(pipelineCode);

        // 如果等于0 则关闭
        if (triggerSetting.getIsRunNotify() == DeleteFlag.NOT_DELETE) {
            return Collections.emptyList();
        }
        if (triggerSetting == null || StringUtils.isEmpty(triggerSetting.getNotifyReceiverList()) || triggerSetting.getNotifyReceiverType() == null) {
            return Collections.emptyList();
        }

        List<String> userRes = new ArrayList<>();


        if (triggerSetting.getNotifyReceiverType() == NotifyReceiverTypeConstant.USER) {
            String[] pipelineNotifyRoles = triggerSetting.getNotifyReceiverList().split(",");
            userRes.addAll(Arrays.asList(pipelineNotifyRoles));
        } else if (triggerSetting.getNotifyReceiverType() == NotifyReceiverTypeConstant.ROLE) {
            Pipeline pipeline = pipelineDomainService.query(pipelineCode);
            if (pipeline == null || StringUtils.isEmpty(pipeline.getComponentLabel())) {
                throw new RuntimeException("pipeline not exists ");
            }
            Component component = componentDomainService.query(pipeline.getComponentLabel());
            if (component == null) {
                throw new RuntimeException("component not exists ");
            }
            String[] pipelineNotifyRoles = triggerSetting.getNotifyReceiverList().split(",");
            for (String pipelineNotifyRole : pipelineNotifyRoles) {
                NgacAssociateDTO ngacAssociateDTO = new NgacAssociateDTO();
                ngacAssociateDTO.setObjectType(ResourceTypeConstant.COMPONENT);// 资源类型
                ngacAssociateDTO.setObjectId(component.getCode());// 资源ID
                List<NgacAssociateDTO> list = ngacManagerService.findNgacAssociate(ngacAssociateDTO);
                for (NgacAssociateDTO associateDTO : list) {
                    if (associateDTO != null && StringUtils.isNotBlank(associateDTO.getUserAttribute()) && associateDTO.getUserAttribute().contains(pipelineNotifyRole)) {
                        userRes.add(associateDTO.getTargetUser());
                    }
                }
            }
        }

        return userRes;

    }

    private void addTaskInstanceByConfig(PipelineConfigDTO pipelineConfig, String pipelineInstanceCode,
                                         List<TaskDef> taskDefs) {
        //任务定义  uuid与模板RefTag关系
        HashMap<String, String> taskDefRefMap =
                taskDefs.stream().collect(HashMap::new, (m, v) -> m.put(v.getUuid(), v.getRefTag()), HashMap::putAll);
        pipelineConfig.getTaskList().forEach(task -> {
            TaskInstance taskInstance = ConfigToInstanceConverter.INSTANCE.toTaskInstance(task);
            taskInstance.setPipelineInstanceCode(pipelineInstanceCode);
            //pod名规则  =>  实例code - refTag - pod （  my-co-o3u8d111018-git-clone-pod  ）
            taskInstance.setCode(pipelineInstanceCode + "-" + taskDefRefMap.get(task.getTaskDefUuid()) + "-pod");
            if (task.getParentUuid().equals("0")) {
                //第一个节点应该直接运行了
                taskInstance.setTaskStatus(TaskInstanceEnum.running.getKey());
            }
            setInstanceTaskOut(pipelineConfig, taskInstance);
            taskInstanceDomainService.add(taskInstance);
        });

    }

    private void setInstanceTaskOut(PipelineConfigDTO pipelineConfig, TaskInstance taskInstance) {
        Gson gson = new Gson();
        HashMap<String, String> hashMap = TektonUtil.parseTaskParamMap2O(taskInstance.getParams());
        ApiResult<List<ArtifactToolDTO>> apiResult;
        if (taskInstance.getCode().contains("deploy")) {
            try {
//                apiResult = artifactToolService.withoutDataArtifactToolList(ArtifactTypeEnum.DOCKER.getKey());
                ArtifactToolQuery query = new ArtifactToolQuery();
                query.setArtifactType(ArtifactTypeEnum.DOCKER.getKey());
                query.setDataSource(ArtifactDataSourceEnum.TOOL.getKey());
                apiResult = artifactToolService.conditionalArtifactToolList(query);
            } catch (Exception e) {
                log.info("获取远程制品仓库信息失败", e);
                throw new BizException("获取远程制品仓库信息失败");
            }
            Map<String, AuthConfig> auths = new HashMap<>();
            for (ArtifactToolDTO artifactTool : apiResult.getData()) {
                try {
                    String password = CryptoUtils.decryptBySRSA(Constant.PRIVATE_KEY_S, artifactTool.getPassword());
                    if (!StringUtils.isBlank(password)) {
                        String base64Auth = TektonUtil.getBase64(artifactTool.getUserName() + ":" + password);
                        AuthConfig ac = new AuthConfig();
                        ac.setAuth(base64Auth);
                        String replaceServer = TektonUtil.extractDomainAndPort(artifactTool.getServerAddress());
                        if (!StringUtils.isBlank(replaceServer)) {
                            auths.put(replaceServer, ac);
                        }
                    }
                } catch (Exception e) {
                    log.info("获取镜像仓库凭证失败", e);
                    throw new BizException("获取镜像仓库凭证失败:" + e);
                }
            }
            DockerConfig dockerConfig = new DockerConfig();
            dockerConfig.setAuths(auths);
            String auth = TektonUtil.getBase64(JSONObject.toJSONString(dockerConfig));

            String applicationYamlStr = TektonUtil.readFileString(Constant.DEPLOY_APPLICATION_TEMPLATE_PATH);
            // 部署容器的名字 pipelineConfig.getBaseInfo().getComponentLabel() + "-" + environment.getCode();
            String componentLabel = pipelineConfig.getBaseInfo().getComponentLabel();
            String deploymentName = componentLabel;
            if (DeployStrategyEnum.Grayscale_publish.getKey().equals(hashMap.get("deployStrategy"))) {
                //根据副本数和批次，当前批次的副本数，, 旧deployment的名字， 旧deploy的副本， 新deployment的名字
                Integer newDeployreplicas = new BigDecimal(String.valueOf(hashMap.get("replicas"))).intValueExact() / new BigDecimal(String.valueOf(hashMap.get("batchesNum"))).intValueExact();
                deploymentName = componentLabel + "-" + redisHelper.incrby(Constant.GRAY_DEPLOYMENT_VERSION_KEY + componentLabel, 1).toString();
                hashMap.put("replicas", newDeployreplicas.toString());
            }
            applicationYamlStr = applicationYamlStr.replace("[componentLabel]", componentLabel);
            applicationYamlStr = applicationYamlStr.replace("[deploymentName]", deploymentName);
            applicationYamlStr = applicationYamlStr.replace("[auth]", auth);
            for (Map.Entry<String, String> entry : hashMap.entrySet()) {
                if ("memory".equals(entry.getKey())) {
                    //memory一定要是整数处理不能是 10.0
                    int memory = new BigDecimal(String.valueOf(entry.getValue())).intValueExact();
                    applicationYamlStr = applicationYamlStr.replace("[" + entry.getKey() + "]", String.valueOf(memory));
                }
                applicationYamlStr = applicationYamlStr.replace("[" + entry.getKey() + "]", String.valueOf(entry.getValue()));

            }
            taskInstance.setOutput(JSON.toJSONString(applicationYamlStr));
        }
        if (taskInstance.getCode().contains("kaniko")) {
            String imageTag = pipelineConfig.getBaseInfo().getComponentLabel() + ":" + TektonUtil.getNowTime();
            if (StringUtils.isNotBlank(hashMap.get("imageTag"))) {
                imageTag = hashMap.get("imageTag");
            }
            String ImageRepoId = hashMap.get("imageUrl");
            ApiResult<ArtifactToolDTO> result;
            try {
                result = artifactToolService.queryArtifactTool(ImageRepoId);
            } catch (Exception e) {
                log.info("获取镜像仓库地址失败", e);
                throw new BizException("获取镜像仓库地址失败");
            }
            ArtifactToolDTO artifactToolDTO = result.getData();
            String serverAddress = artifactToolDTO.getServerAddress().replace("http://", "").replace("https://", "");
            if (serverAddress.endsWith("/")) {
                // 去掉最后的'/'
                serverAddress = serverAddress.substring(0, serverAddress.length() - 1);
            }
            String image = serverAddress + "/" + imageTag;
            taskInstance.setOutput(image);
        }
        if (taskInstance.getCode().contains("prove")) {
            String sign = TektonUtil.getBase64(TracingUtils.getUserName() + "+" + TektonUtil.getNowTime());
            taskInstance.setOutput(sign);
        }
    }

    private PipelineInstance getPipelineInstanceByConfig(PipelineConfigDTO pipelineConfig, Integer triggerType) {
        PipelineDTO baseInfo = pipelineConfig.getBaseInfo();
        PipelineInstance pipelineInstance = ConfigToInstanceConverter.INSTANCE.toPipelineInstance(baseInfo);
        pipelineInstance.setTriggerType(triggerType);
        String redisKey = Constant.PIPELINE_BUILD_NUM_KEY + baseInfo.getComponentLabel() + "." + baseInfo.getEnvironmentUuid();
        Long buildNum = redisHelper.incrby(redisKey, 1);
        pipelineInstance.setBuildNumber(Math.toIntExact(buildNum));
        pipelineInstance.setContextInfo(JSON.toJSONString(pipelineConfig.getVariableSettingList()));
        return pipelineInstance;
    }


    private Cluster getClusterByEnv(Environment environment) {
        BizAssert.notNull(environment, "环境不存在");
        Space space = spaceDomainService.query(environment.getSpaceUuid());
        BizAssert.notNull(space, "交付空间不存在");
        Cluster cluster = clusterDomainService.query(space.getClusterUuid());
        BizAssert.notNull(cluster, "集群不存在");
        return cluster;
    }

    @Data
    public static class DockerConfig {
        private Map<String, AuthConfig> auths;
    }

    @Data
    public static class AuthConfig {
        private String auth;
    }
}
